package fr.fbhelp.files
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.filesystem.File;
	import flash.utils.Dictionary;
	
	import fr.fbhelp.events.ParserEvent;
	import fr.fbhelp.parsing.ParseManager;
	
	import mx.controls.Alert;
	import mx.core.FlexGlobals;
	import mx.events.CloseEvent;
	
	public class CopyFilesQueue
	{
		private var globalDispatcher:IEventDispatcher;
		
		private var copyItems:Dictionary = new Dictionary();
		
		public function CopyFilesQueue()
		{
			globalDispatcher = FlexGlobals.topLevelApplication as IEventDispatcher;
		}
		
		public function addItem(source:String, destination:String):void
		{
			var copyItem:CopyFileItem = new CopyFileItem();
			copyItem.source = source;
			copyItem.destination = destination;

			copyItems[source] = copyItem;
		}
		
		public function removeItem(source:String):void
		{
			if (copyItems[source] != null)
			{
				delete copyItems[source];	
			}
		}
		
		public function initCopying():void
		{
			var infoString:String = "Help directories will be copied: \n\n";
			var index:int = 1;
			for each (var copyItem: CopyFileItem in copyItems)
			{
				infoString += "" + index + ": " + copyItem.toString() + "\n\n";
				index++;
			}
			
			infoString += "This may take up to few minutes to copy big dirs. Let's start copying now?";
			
			showCopyFilesPrompt(infoString);
		}
		
		private function showCopyFilesPrompt(infoString:String):void
		{
			
			Alert.show(infoString, ParseManager.TITLE_COPY_HELP_DIRS, 
				(Alert.YES | Alert.NO), null, onCopyFilesPromptClose, null, Alert.YES );
		}

		private function onCopyFilesPromptClose(event:CloseEvent):void
		{
			trace("Copy files prompt closed, event " + event);
			
			if (event.detail == Alert.YES)
			{
				copyNextFile();
			}
			
			if (event.detail == Alert.NO)
			{
				dontCopy();
			}
		}
		
		private function copyNextFile():void
		{
			for each (var copyItem: CopyFileItem in copyItems)
			{
				break;
			}
			
			if (copyItem == null)
			{
				finalizeQueue();
				return;
			}
			
			removeItem(copyItem.source);
			
			Output.append("\nStart copying: " + copyItem);
			
			var copyingStartedEvent:ParserEvent = new ParserEvent(ParserEvent.HELP_DIR_COPYING_STARTED, true);
			FlexGlobals.topLevelApplication.dispatchEvent(copyingStartedEvent);
			
			var file:File = new File().resolvePath(copyItem.source);
			var destFile: File = new File().resolvePath(copyItem.destination); 
			file.copyToAsync(destFile, true);
			file.addEventListener(Event.COMPLETE, onFileCopyComplete, false, 0, true);
			file.addEventListener(IOErrorEvent.IO_ERROR, onFileCopyIOError, false, 0, true);
		}
		
		private function dontCopy():void
		{
			Output.append("Copying has been cancelled.");
			finalizeQueue();
		}

		private function onFileCopyComplete(event:Event):void
		{
			Output.append("Copy operation complete: " + (event.target as File).name );
			
			var copyingFinishedEvent:ParserEvent = new ParserEvent(ParserEvent.HELP_DIR_COPYING_FINISHED, true);
			FlexGlobals.topLevelApplication.dispatchEvent(copyingFinishedEvent);

			removeCopyListeners(event.target as File);
			copyNextFile();
		}

		private function onFileCopyIOError(event:IOErrorEvent):void
		{
			trace("Copy IO Error: " + event.text );
			removeCopyListeners(event.target as File);
			copyNextFile();

			var copyingFinishedEvent:ParserEvent = new ParserEvent(ParserEvent.HELP_DIR_COPYING_FINISHED, true);
			FlexGlobals.topLevelApplication.dispatchEvent(copyingFinishedEvent);
		}

		private function removeCopyListeners(file:File):void
		{
			file.removeEventListener(Event.COMPLETE, onFileCopyComplete, false);
			file.removeEventListener(IOErrorEvent.IO_ERROR, onFileCopyIOError, false);
		}
		
		private function finalizeQueue():void
		{
			Output.append("Copying Queue is finished.");
			
			var event:Event = new ParserEvent(ParserEvent.HELP_WAS_COPIED, true);
			globalDispatcher.dispatchEvent(event)
		}
	}
}